package com.pokermind.common.util;

import java.util.*;

/**
 * 牌桌座位配置工具
 * 
 * V4.4: 支持6人、7人、8人、9人满桌的标准座位配置
 * 
 * 提供不同人数牌桌的标准位置定义和座位映射
 * 
 * @author PokerMind Team
 * @version V4.4
 */
public class TablePositionConfig {
    
    /**
     * 标准9人满桌位置（Full Ring）
     * 按顺时针顺序：从按钮位开始
     */
    public static final List<String> FULL_RING_9 = Collections.unmodifiableList(Arrays.asList(
        "BTN", "SB", "BB", "UTG", "UTG+1", "UTG+2", "LJ", "HJ", "CO"
    ));
    
    /**
     * 8人桌位置配置
     * 省略UTG+2，保留其他位置
     */
    public static final List<String> TABLE_8 = Collections.unmodifiableList(Arrays.asList(
        "BTN", "SB", "BB", "UTG", "UTG+1", "LJ", "HJ", "CO"
    ));
    
    /**
     * 7人桌位置配置
     * 省略UTG+2和UTG+1
     */
    public static final List<String> TABLE_7 = Collections.unmodifiableList(Arrays.asList(
        "BTN", "SB", "BB", "UTG", "LJ", "HJ", "CO"
    ));
    
    /**
     * 6人桌位置配置（6-max）
     * 最常见的短桌配置
     */
    public static final List<String> TABLE_6 = Collections.unmodifiableList(Arrays.asList(
        "BTN", "SB", "BB", "UTG", "HJ", "CO"
    ));
    
    /**
     * 所有有效位置的完整集合（9人桌标准）
     */
    public static final Set<String> ALL_VALID_POSITIONS = Collections.unmodifiableSet(
        new LinkedHashSet<>(FULL_RING_9)
    );
    
    /**
     * 位置到座位号的映射（9人桌）
     * 座位号1-9
     */
    private static final Map<String, Integer> POSITION_TO_SEAT_9 = new HashMap<>();
    
    static {
        // 9人桌标准座位映射
        POSITION_TO_SEAT_9.put("BTN", 9);
        POSITION_TO_SEAT_9.put("SB", 1);
        POSITION_TO_SEAT_9.put("BB", 2);
        POSITION_TO_SEAT_9.put("UTG", 3);
        POSITION_TO_SEAT_9.put("UTG+1", 4);
        POSITION_TO_SEAT_9.put("UTG+2", 5);
        POSITION_TO_SEAT_9.put("LJ", 6);
        POSITION_TO_SEAT_9.put("HJ", 7);
        POSITION_TO_SEAT_9.put("CO", 8);
    }
    
    /**
     * 根据玩家数量获取标准位置配置
     * 
     * @param playerCount 玩家数量
     * @return 位置列表（从按钮位顺时针）
     * @throws IllegalArgumentException 如果人数不支持
     */
    public static List<String> getPositionsForPlayerCount(int playerCount) {
        switch (playerCount) {
            case 9:
                return FULL_RING_9;
            case 8:
                return TABLE_8;
            case 7:
                return TABLE_7;
            case 6:
                return TABLE_6;
            case 5:
                // 5人桌：省略HJ
                return Arrays.asList("BTN", "SB", "BB", "UTG", "CO");
            case 4:
                // 4人桌：省略HJ和UTG
                return Arrays.asList("BTN", "SB", "BB", "CO");
            case 3:
                // 3人桌：最简配置
                return Arrays.asList("BTN", "SB", "BB");
            case 2:
                // 2人桌（Heads-up）：BTN兼任SB
                return Arrays.asList("BTN", "BB");
            default:
                throw new IllegalArgumentException("Unsupported player count: " + playerCount + ". Must be 2-9.");
        }
    }
    
    /**
     * 验证位置是否有效
     * 
     * @param position 位置名称
     * @return true表示有效
     */
    public static boolean isValidPosition(String position) {
        return ALL_VALID_POSITIONS.contains(position);
    }
    
    /**
     * 验证位置列表是否符合特定人数的标准配置
     * 
     * @param positions 位置列表
     * @param playerCount 玩家数量
     * @return true表示符合标准
     */
    public static boolean isStandardConfig(List<String> positions, int playerCount) {
        if (positions == null || positions.size() != playerCount) {
            return false;
        }
        
        List<String> standardPositions = getPositionsForPlayerCount(playerCount);
        
        // 检查是否包含所有标准位置（顺序可以不同）
        Set<String> posSet = new HashSet<>(positions);
        Set<String> stdSet = new HashSet<>(standardPositions);
        
        return posSet.equals(stdSet);
    }
    
    /**
     * 获取位置在9人桌中的标准座位号
     * 
     * @param position 位置名称
     * @return 座位号（1-9），如果位置无效返回-1
     */
    public static int getSeatNumberFor9Player(String position) {
        return POSITION_TO_SEAT_9.getOrDefault(position, -1);
    }
    
    /**
     * 获取翻牌后行动顺序（所有人数桌通用规则）
     * 
     * @param positions 当前桌的位置列表
     * @return 按行动顺序排列的位置列表
     */
    public static List<String> getPostFlopActionOrder(List<String> positions) {
        // 翻牌后行动顺序：SB → BB → UTG系列 → LJ → HJ → CO → BTN
        List<String> order = new ArrayList<>();
        
        // 按固定顺序添加存在的位置
        String[] standardOrder = {"SB", "BB", "UTG", "UTG+1", "UTG+2", "LJ", "HJ", "CO", "BTN"};
        Set<String> posSet = new HashSet<>(positions);
        
        for (String pos : standardOrder) {
            if (posSet.contains(pos)) {
                order.add(pos);
            }
        }
        
        return order;
    }
    
    /**
     * 获取翻前行动顺序（除SB/BB外）
     * 
     * @param positions 当前桌的位置列表
     * @return 按行动顺序排列的位置列表
     */
    public static List<String> getPreFlopActionOrder(List<String> positions) {
        // 翻前行动顺序：UTG系列 → LJ → HJ → CO → BTN → SB → BB
        List<String> order = new ArrayList<>();
        
        String[] standardOrder = {"UTG", "UTG+1", "UTG+2", "LJ", "HJ", "CO", "BTN", "SB", "BB"};
        Set<String> posSet = new HashSet<>(positions);
        
        for (String pos : standardOrder) {
            if (posSet.contains(pos)) {
                order.add(pos);
            }
        }
        
        return order;
    }
    
    /**
     * 获取位置分类（早期/中间/后期/盲注）
     * 
     * @param position 位置名称
     * @return 位置分类
     */
    public static PositionCategory getPositionCategory(String position) {
        if (position == null) {
            return PositionCategory.UNKNOWN;
        }
        
        switch (position) {
            case "UTG":
            case "UTG+1":
            case "UTG+2":
                return PositionCategory.EARLY;
            case "LJ":
                return PositionCategory.MIDDLE;
            case "HJ":
            case "CO":
            case "BTN":
                return PositionCategory.LATE;
            case "SB":
            case "BB":
                return PositionCategory.BLINDS;
            default:
                return PositionCategory.UNKNOWN;
        }
    }
    
    /**
     * 位置分类枚举
     */
    public enum PositionCategory {
        EARLY("早期位置", "Early Position"),
        MIDDLE("中间位置", "Middle Position"),
        LATE("后期位置", "Late Position"),
        BLINDS("盲注位", "Blinds"),
        UNKNOWN("未知", "Unknown");
        
        private final String nameZh;
        private final String nameEn;
        
        PositionCategory(String nameZh, String nameEn) {
            this.nameZh = nameZh;
            this.nameEn = nameEn;
        }
        
        public String getNameZh() {
            return nameZh;
        }
        
        public String getNameEn() {
            return nameEn;
        }
    }
    
    /**
     * 获取位置的中文全称
     * 
     * @param position 位置名称
     * @return 中文全称
     */
    public static String getPositionNameZh(String position) {
        if (position == null) {
            return "未知";
        }
        
        switch (position) {
            case "BTN": return "按钮位";
            case "SB": return "小盲位";
            case "BB": return "大盲位";
            case "UTG": return "枪口位";
            case "UTG+1": return "枪口+1";
            case "UTG+2": return "枪口+2";
            case "LJ": return "低劫持位";
            case "HJ": return "高劫持位";
            case "CO": return "关煞位";
            default: return position;
        }
    }
    
    /**
     * 获取位置的英文全称
     * 
     * @param position 位置名称
     * @return 英文全称
     */
    public static String getPositionNameEn(String position) {
        if (position == null) {
            return "Unknown";
        }
        
        switch (position) {
            case "BTN": return "Button";
            case "SB": return "Small Blind";
            case "BB": return "Big Blind";
            case "UTG": return "Under The Gun";
            case "UTG+1": return "UTG Plus One";
            case "UTG+2": return "UTG Plus Two";
            case "LJ": return "Low Jack";
            case "HJ": return "High Jack";
            case "CO": return "CutOff";
            default: return position;
        }
    }
    
    /**
     * 获取支持的最小玩家数
     */
    public static int getMinPlayers() {
        return 2;
    }
    
    /**
     * 获取支持的最大玩家数
     */
    public static int getMaxPlayers() {
        return 9;
    }
    
    /**
     * 检查玩家数量是否在支持范围内
     * 
     * @param playerCount 玩家数量
     * @return true表示支持
     */
    public static boolean isSupportedPlayerCount(int playerCount) {
        return playerCount >= getMinPlayers() && playerCount <= getMaxPlayers();
    }
}

